package common

import (
	"os"
	"path/filepath"
	"strings"

	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var Logger *zap.SugaredLogger

func InitLogger(level string, logFileName string) error {
	stdoutEncoder := initEncoder("console")
	osStdoutSyner := zapcore.AddSync(os.Stdout)
	stdoutCore := zapcore.NewCore(stdoutEncoder, osStdoutSyner, zap.DebugLevel)

	fileEncoder := initEncoder("json")
	// workDir, _ := os.Getwd()
	dir, _ := os.Executable()
	workDir := filepath.Dir(dir)
	fileWriteSyncer, err := initLogFile(
		filepath.Join(workDir, "log/", logFileName), 10, 10, 7, false,
	)
	if err != nil {
		return err
	}
	fielCore := zapcore.NewCore(fileEncoder, fileWriteSyncer, initLogLevel(level))
	core := zapcore.NewTee(stdoutCore, fielCore)
	Logger = zap.New(core).Sugar()
	return nil
}

func initLogLevel(logLevel string) zapcore.Level {
	ll := zap.InfoLevel
	switch strings.ToLower(strings.TrimSpace(logLevel)) {
	case "debug":
		ll = zap.DebugLevel
	case "info":
		ll = zap.InfoLevel
	case "warn":
		ll = zap.WarnLevel
	case "error":
		ll = zap.ErrorLevel
	case "panic":
		ll = zap.PanicLevel
	case "fatal":
		ll = zap.FatalLevel
	}
	return ll
}

func initLogFile(logFilePath string, maxSize, maxBackup, maxAge int, compress bool) (zapcore.WriteSyncer, error) {
	lumberJackLogger := &lumberjack.Logger{
		Filename: logFilePath,
		MaxSize:  maxSize,
		MaxAge:   maxAge,
		Compress: compress,
	}
	return zapcore.AddSync(lumberJackLogger), nil
}

func initEncoder(format string) zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	var core zapcore.Encoder
	switch strings.ToLower(strings.TrimSpace(format)) {
	case "json":
		core = zapcore.NewJSONEncoder(encoderConfig)
	case "console":
		core = zapcore.NewConsoleEncoder(encoderConfig)
	default:
		core = zapcore.NewConsoleEncoder(encoderConfig)
	}
	return core
}
